<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
</html>
<script>
  function Promise(executor) {
    this.status = "pending"; // 初始化状态为待定
    this.value = null; // 初始化值
    this.reason = null; // 初始化原因
    this.callbacks = []; // 存储then方法回调函数
    if (typeof executor === "function") {
      // 如果executor是一个函数
      try {
        // 执行executor函数并传入resolve和reject方法
        executor(resolve.bind(this), reject.bind(this));
      } catch (e) {
        // 如果executor函数抛出异常，调用reject方法
        reject(e);
      }
    }
  }

  Promise.prototype.then = function (onFulfilled, onRejected) {
    let promise2 = new Promise((resolve, reject) => {
      // 创建新的Promise实例
      let x; // 存储上一个Promise的状态和值/原因
      if (typeof onFulfilled !== "function" && this.status === "fulfilled") {
        // 如果onFulfilled不是函数且上一个Promise状态为成功
        x = this.value; // 将上一个Promise的值保存到x
        resolve(x); // 调用resolve方法，将x作为新Promise的值
        return; // 直接返回，结束函数
      } else if (
        typeof onRejected !== "function" &&
        this.status === "rejected"
      ) {
        // 如果onRejected不是函数且上一个Promise状态为失败
        x = this.reason; // 将上一个Promise的原因保存到x
        reject(x); // 调用reject方法，将x作为新Promise的原因
        return; // 直接返回，结束函数
      } else {
        // 如果onFulfilled或onRejected是函数或上一个Promise的状态为待定
        this.callbacks.push({
          // 将回调函数保存到回调队列中
          fulfilled: onFulfilled,
          rejected: onRejected,
        });
        if (this.status === "pending") {
          // 如果上一个Promise状态为待定，直接返回，结束函数
          return;
        } else if (this.status === "fulfilled") {
          // 如果上一个Promise状态为成功，调用fulfilled回调函数并将值保存到x
          x = this.value;
          resolve(onFulfilled(x));
        } else if (this.status === "rejected") {
          // 如果上一个Promise状态为失败，调用rejected回调函数并将原因保存到x
          x = this.reason;
          reject(onRejected(x));
        }
      }
    });
    return promise2; // 返回新的Promise实例
  };
</script>
